package org.ltt.rbac.config;

import jakarta.annotation.Resource;
import org.ltt.rbac.config.handler.UnAccessDeniedHandler;
import org.ltt.rbac.config.handler.UnLoginAuthenticationEntryPoint;
import org.ltt.rbac.filter.AuthenticationTokenFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author ltt
 * @date 2020/6/1 14:32
 * @version 1.0
 * @description
 *
 * web security 自定义配置
 */
@Configuration
public class SecurityConfig {
    /**
     * 未认证或者登录，访问系统
     */
    @Resource
    private UnLoginAuthenticationEntryPoint unLoginAuthenticationEntryPoint;

    /**
     * token认证过滤器
     */
    @Resource
    private AuthenticationTokenFilter authenticationTokenFilter ;

    /**
     * 未授权访问处理
     */
    @Resource
    private UnAccessDeniedHandler unAccessDeniedHandler;

    /**
     * 自定义过滤链
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
        String[] whitePathList = { "/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**", "/configuration/**", "/swagger-ui/**"};
        http
                //校验认证逻辑
                .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                //如果使用jwt进行token认证的话，可以禁用crsf
                //crsf开启后，下面放行的post接口无法通过，需要在请求中配置_crsf等参数
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/auth/login").permitAll()//放行的接口 无需认证的接口登录
                        .requestMatchers("/auth/register").permitAll()//放行的接口 无需认证的接口登录
                        .requestMatchers(whitePathList).permitAll()//放行的接口 无需认证的接口登录
                        .requestMatchers(HttpMethod.OPTIONS).permitAll()
                        .anyRequest().authenticated()// 要求所有访问都必须通过认证
                )
                // 未登录或者授权情况下 处理逻辑
                .exceptionHandling(exception -> exception
                        .authenticationEntryPoint(unLoginAuthenticationEntryPoint)
                        .accessDeniedHandler(unAccessDeniedHandler)
                )
                //// 如果你仍然需要支持基于表单的登录，可以保留这部分配置，并确保处理器返回JSON
//                .formLogin(form -> form
//                        .
//
//                )
                //不会创建会话
                .sessionManagement(
                        session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                );
        //禁用缓存
        return http.build();
    }

//    /**
//     * 加密算法
//     * @return
//     */
//    @Bean
//    public PasswordEncoder passwordEncoder(){
//        return new BCryptPasswordEncoder(10);
//    }


}
